<?php
/**
 * This file is part of webman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author    walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link      http://www.workerman.net/
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */

use Webman\Route;

// 映射成 yii2 风格
$route = function ($uri, $cb, $method = '') {
    if (in_array(strtoupper($method), ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'])) {
        $method = strtolower($method);
    } else {
        $method = 'any';
    }
    Route::$method($uri, $cb);
};

$dir_iterator = new \RecursiveDirectoryIterator(app_path());
$iterator = new \RecursiveIteratorIterator($dir_iterator);
foreach ($iterator as $file) {
    // 忽略目录和非php文件
    if (is_dir($file) || $file->getExtension() != 'php') {
        continue;
    }

    $file_path = str_replace('\\', '/', $file->getPathname());
    // 文件路径里不带controller的文件忽略
    if (strpos($file_path, 'controller') === false) {
        continue;
    }
    // 根据文件路径是被类名
    $class_name = str_replace('/', '\\', substr(substr($file_path, strlen(base_path())), 0, -4));
    if (!class_exists($class_name)) {
        // echo "Class $class_name not found, skip route for it\n";
        continue;
    }
    // 通过反射找到这个类的所有共有方法作为action
    $class = new ReflectionClass($class_name);
    if (!$class->implementsInterface(\app\component\BaseController::class)) {
        continue;
    }

    // 根据文件路径计算uri
    $controller = basename($file_path);
    $controllerName = substr($controller, 0, -14); // 去掉最后的action
    $uri_path = str_replace('controller/', '', substr($file_path, strlen(app_path())));
    $uri_path = str_replace($controller, '', $uri_path);
    $uri_path .= \app\helper\StringHelper::camel2id($controllerName);

    $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);

    // 设置路由
    foreach ($methods as $item) {
        $actionName = $item->name;
        if (!\app\helper\StringHelper::startsWith($actionName, 'action')) {
            continue;
        }
        // 获取名称
        $action = substr($actionName, 6);
        $action = \app\helper\StringHelper::camel2id($action);
        // action为index时uri里末尾/index可以省略
        if ($action === 'index') {
            // controller也为index时可以uri里可以省略/index/index
            if (substr($uri_path, -6) === '/index') {
                if ($uri_path === '/index') {
                    $route('', [$class_name, $actionName]);
                    $route('/', [$class_name, $actionName]);
                }
                $route($uri_path, [$class_name, $actionName]);
                $route($uri_path . '/', [$class_name, $actionName]);
            }
        }
        $route($uri_path . '/' . $action, [$class_name, $actionName]);
    }

    // 子目录的path
    $actionsPath = dirname($file_path) . '/' . lcfirst($controllerName);
    if (!is_dir($actionsPath)) {
        continue;
    }
    $actionsIterator = new \RecursiveDirectoryIterator($actionsPath);
    $iterator = new \RecursiveIteratorIterator($actionsIterator);
    foreach ($iterator as $actionFile) {
        // 忽略目录和非php文件
        if (is_dir($actionFile) || $actionFile->getExtension() != 'php') {
            continue;
        }

        $actionPath = str_replace('\\', '/', $actionFile->getPathname());
        // 根据文件路径是被类名
        $class_name = str_replace('/', '\\', substr(substr($actionPath, strlen(base_path())), 0, -4));
        if (!class_exists($class_name)) {
            // echo "Class $class_name not found, skip route for it\n";
            continue;
        }
        // 通过反射找到这个类的所有共有方法作为action
        $class = new ReflectionClass($class_name);
        if (!$class->implementsInterface(\app\component\BaseAction::class)) {
            continue;
        }
        // 根据文件路径计算uri
        $action = basename($actionPath);
        $actionName = substr($action, 0, -10); // 去掉最后的action
        if (\app\helper\StringHelper::camel2id($actionName) === 'index') {
            $route($uri_path . '/', [$class_name, 'run']);
        }

        $route($uri_path . '/' . \app\helper\StringHelper::camel2id($actionName), [$class_name, 'run']);
    }
}
